package com.xuecheng.media.service.impl;

import com.alibaba.nacos.common.http.param.MediaType;
import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import com.xuecheng.base.exception.GlobalException;
import com.xuecheng.media.manager.ObsManager;
import com.xuecheng.media.mapper.MediaFilesMapper;
import com.xuecheng.media.model.dto.UploadFileResultDto;
import com.xuecheng.media.model.dto.UploadFilesParamsDto;
import com.xuecheng.media.model.po.MediaFiles;
import com.xuecheng.media.service.FileUploadService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * @Author FengHuan Wang
 * @Date 2025/3/31 16:26
 * @Version 1.0
 */
@Service
@Slf4j
public class FileUploadServiceImpl implements FileUploadService {

    @Resource
    ObsManager obsManager;

    @Resource
    MediaFilesMapper mediaFilesMapper;


    /**
     * 获取文件存储路径
     * @return
     */
    private String getDefaultFolderPath(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String floder = simpleDateFormat.format(new Date()).replace("-", "/") + "/";
        return floder;
    }

    /**
     * 获取文件的md5值
     * @param file
     * @return
     */
    private String getFileMd5(File file){
        try(FileInputStream fileInputStream = new FileInputStream(file)){
            String fileMd5 = DigestUtils.md5DigestAsHex(fileInputStream);
            return fileMd5;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    private String getMimeType(String extension){
        String mimeType = "";
        if (extension == null){
            extension = "";
            // 根据扩展名取出类型
            ContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(extension);
            // 通用mimeType, 字节流
            mimeType = MediaType.APPLICATION_OCTET_STREAM;
            if (extensionMatch != null){
                mimeType = extensionMatch.getMimeType();
            }
        }
        return mimeType;
    }

    /**
     * 保存文件信息到数据库
     * @param companyId
     * @param fileMd5
     * @param uploadFilesParamsDto
     * @param objectName
     * @return
     */
    public MediaFiles addMediaFilesToDb(Long companyId, String fileMd5, UploadFilesParamsDto uploadFilesParamsDto, String objectName, String filePath){
        // 从数据库中查询文件
        MediaFiles mediaFiles = mediaFilesMapper.selectById(fileMd5);
        if (mediaFiles == null){
            mediaFiles = new MediaFiles();
            // 拷贝基本信息
            BeanUtils.copyProperties(uploadFilesParamsDto, mediaFiles);
            mediaFiles.setId(fileMd5);
            mediaFiles.setCompanyId(companyId);
            mediaFiles.setBucket(null);
            mediaFiles.setFilePath(objectName);
            mediaFiles.setFileId(fileMd5);
            mediaFiles.setUrl(filePath);
            mediaFiles.setCreateDate(LocalDateTime.now());
            mediaFiles.setChangeDate(LocalDateTime.now());
            mediaFiles.setAuditStatus("002003");
            // 保存文件信息到文件表
            int insert = mediaFilesMapper.insert(mediaFiles);
            if (insert < 0){
                log.error("保存文件信息失败");
                GlobalException.cast("保存文件信息失败");
            }
        }
        return mediaFiles;
    }

    /**
     * 上传文件
     * @param companyId
     * @param uploadFilesParamsDto
     * @param localFilePath
     * @return
     */
    @Override
    @Transactional
    public UploadFileResultDto uploadFile(Long companyId, UploadFilesParamsDto uploadFilesParamsDto, String localFilePath){
        File file = new File(localFilePath);
        if (!file.exists()){
            GlobalException.cast("文件不存在");
        }
        // 文件名称
        String filename = uploadFilesParamsDto.getFilename();
        // 文件扩展名
        String substring = filename.substring(filename.lastIndexOf("."));
        // 文件的md5值
        String fileMd5 = getFileMd5(file);
        // 文件的默认目录
        String defaultFolderPath = getDefaultFolderPath();
        // 存储到obs的对象名
        String objectName = defaultFolderPath + fileMd5 + substring;
        // 上传文件到obs
        String upload = "";
        try {
            upload = obsManager.upload(defaultFolderPath, fileMd5, substring);
        } catch (IOException e) {
            GlobalException.cast("上传文件失败");
        }
        // 文件大小
        uploadFilesParamsDto.setFileSize(file.length());
        // 将文件信息存储到数据库
        MediaFiles mediaFiles = addMediaFilesToDb(companyId, fileMd5, uploadFilesParamsDto, upload, objectName);
        // 准备返回数据
        UploadFileResultDto uploadFileResultDto = new UploadFileResultDto();
        BeanUtils.copyProperties(mediaFiles, uploadFileResultDto);
        return uploadFileResultDto;
    }
}
